#ifndef MODEL_MOLECULE_VISITOR_H
#define MODEL_MOLECULE_VISITOR_H

// These are fwd decls becase not everyone implementing a Molecule Visitor
// interface might be interested in all the elements it may iterate. By not
// including the headers for Atom, Atom_Element and Fragment we are avoiding
// some unwanted dependencies.
// Again, as not all the implementations of Molecule_Visitor will be interested
// in all the elements it could be notified of, we provide a default impelmentation.
class Atom;
class Atom_Element;
class Fragment;

/**
 * Molecule visitor interface; used when a class needs to "iterate" a molecule.
 * The logic for actually iterating a molecule (the HOW) will be in a molecule
 * reader, yet WHAT to do will be known by whoever implements this interface.
 * Provides a way to know when an atom or a type were read. Also provides a
 * callback to know when a fragment was found (I.E. when an aminoacid has been
 * completely read. Will notify the implementation, for exmaple, that an
 * Glicyne was found, though wheter this is an aminoacid or some other random
 * particle will depend on the fragment search. @see Molecule_reader for more
 * details).
 */
class Molecule_Visitor
{
public:
    virtual ~Molecule_Visitor() {}
    virtual void on_fragment_start() {}
    virtual void on_fragment_start(Fragment* previous_fragment, Fragment* fragment) {}
    virtual void on_type_found(const Atom_Element* type) {}
    virtual void on_atom_found(const Atom* atom, const Atom_Element* type) {}
};

#endif /* MODEL_MOLECULE_VISITOR_H */
